package com.nipun.graph.utils;

import java.util.Hashtable;

import org.jaxen.NamespaceContext;
import org.w3c.dom.Attr;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;

public class DerivedNameSpaceContext implements NamespaceContext {

	private static final String _NULL_PREFIX = "";
	private static final String _XMLNS = /*NOI18N*/"xmlns";

	private Element _element;
	private Hashtable _namespaces;
	private Hashtable _defaultNamespaces;

	
	public DerivedNameSpaceContext(Element el, Hashtable defaultNS){
		_element = el;
		_defaultNamespaces = defaultNS;
	}
	
	public String translateNamespacePrefixToUri(String prefix)
	{
		// Special case - if no prefix is specified then return a null value.
		if (prefix == null || prefix.length() == 0) {
			return null;
		}

		// If the prefix is defined in the set of default namespaces, then
		// this takes precedence over any namespaces declared in the XML
		// document.
		String namespace = (String)_defaultNamespaces.get(prefix);
		if (namespace != null) {
			return namespace;
		}

		// First check to see if the namespaces in effect for the element have
		// been processed.
		if (_namespaces == null) {
			_namespaces = new Hashtable(5, 1.0f);

			// Walk up the tree to the document node, adding namespace
			// declarations as they are found.
			Node node = _element;
			while (node != null && node.getNodeType() == Node.ELEMENT_NODE) {
				NamedNodeMap children = node.getAttributes();
				int len = children != null ? children.getLength() : 0;
				for (int i = 0; i < len; i++) {
					Attr child = (Attr)children.item(i);
					String attrName = child.getLocalName();
					String attrPrefix = child.getPrefix();
					if (attrPrefix != null) {
						if (attrPrefix.equals(_XMLNS)) {
							if (!_namespaces.containsKey(attrName)) {
								_namespaces.put(attrName, child.getValue());
							}
						}
					}
					else if (attrName != null && attrName.equals(_XMLNS)) {
						if (!_namespaces.containsKey(_NULL_PREFIX)) {
							_namespaces.put(_NULL_PREFIX, child.getValue());
						}
					}
				}

				node = node.getParentNode();
			}
		}

		return (String)_namespaces.get(prefix);
	}

}
